package org.jeecg.modules.file;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.event.ProgressEvent;
import com.aliyun.oss.event.ProgressEventType;
import com.aliyun.oss.event.ProgressListener;
import com.aliyun.oss.model.PutObjectRequest;
import org.jeecg.common.api.vo.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 文件上传
 */
// 使用进度条，需要实现ProgressListener方法
@RestController
@RequestMapping("/api/oss/file/up")
public class PutObjectProgressListener implements ProgressListener {

    private static Logger logger = LoggerFactory.getLogger(PutObjectProgressListener.class);
    private static final Random random = new Random();

    private long bytesWritten = 0;
    private long totalBytes = -1;

    @RequestMapping(value = "/upload", method = RequestMethod.POST, headers = { "content-type=multipart/form-data" })
    public Result uploadFile(@RequestParam("file") MultipartFile file,
                             @RequestParam(name="module",required=false) String module) throws IOException {

        // 创建OSSClient实例（OSS客户端实例）
        OSS ossClient = new OSSClientBuilder().build(OssConfig.ENDPOINT,
                OssConfig.KEY_ID, OssConfig.KEY_SECRET);
        logger.info(module);
        InputStream inputStream = file.getInputStream();
        String originalFilename = file.getOriginalFilename();

        // 获取文件的扩展名
        String extension = originalFilename.contains(".") ? originalFilename.substring(originalFilename.lastIndexOf(".")) : "";

        // 生成四位随机数
//        int randomNum = random.nextInt((int) Math.pow(10, 4));
//        String randomSuffix = String.format("%04d", randomNum);
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");

        StringBuilder sb=new StringBuilder();
        sb.append(sdf.format(new Date()));
        Random rnd=new Random();
        sb.append(rnd.nextInt(100));


        // 构造新的文件名，将随机数作为后缀添加到原始文件名前，保留文件扩展名
        String objectName =module + "/" + sb + "_" + originalFilename.substring(0, originalFilename.lastIndexOf(".")) +
                  extension;

        boolean uploadSucceed = false;

        try {
            ossClient.putObject(new PutObjectRequest(OssConfig.BUCKET_NAME, objectName, inputStream));
            uploadSucceed = true;
        } catch (OSSException oe) {
            // ... 异常处理代码
        } catch (ClientException ce) {
            // ... 异常处理代码
        } finally {
            ossClient.shutdown();
        }

        if (uploadSucceed) {
            logger.info("上传成功");
            String fileUrl = "https://" + OssConfig.BUCKET_NAME + "." + OssConfig.ENDPOINT + "/" + objectName;
            return Result.ok(fileUrl);
        } else {
            logger.info("上传失败");
            return Result.error("上传失败");
        }
    }

    // 使用进度条需要您重写回调方法，以下仅为参考示例。
    @Override
    public void progressChanged(ProgressEvent progressEvent) {
        long bytes = progressEvent.getBytes();
        ProgressEventType eventType = progressEvent.getEventType();
        switch (eventType) {
            case TRANSFER_STARTED_EVENT:
                logger.info("Start to upload......");
                break;
            case REQUEST_CONTENT_LENGTH_EVENT:
                this.totalBytes = bytes;
                logger.info(this.totalBytes + " bytes in total will be uploaded to OSS");
                break;
            case REQUEST_BYTE_TRANSFER_EVENT:
                this.bytesWritten += bytes;
                if (this.totalBytes != -1) {
                    int percent = (int) (this.bytesWritten * 100.0 / this.totalBytes);
                    logger.info(bytes + " bytes have been written at this time, upload progress: " + percent + "%(" + this.bytesWritten + "/" + this.totalBytes + ")");
                } else {
                    logger.info(bytes + " bytes have been written at this time, upload ratio: unknown" + "(" + this.bytesWritten + "/...)");
                }
                break;
            case TRANSFER_COMPLETED_EVENT:
                logger.info("Succeed to upload, " + this.bytesWritten + " bytes have been transferred in total");
                break;
            case TRANSFER_FAILED_EVENT:
                logger.info("Failed to upload, " + this.bytesWritten + " bytes have been transferred");
                break;
            default:
                break;
        }
    }
}